`timescale 1ns / 1ps

module MyDFF8bit_withAsy_tb;

    reg         clk;
    reg         rst;
    reg  [7:0]  D;
    reg  [7:0]  AsyncVal;
    wire [7:0]  Q;

    // DUT 实例化
    MyDFF8bit_withAsy uut (
        .clk(clk),
        .rst(rst),
        .D(D),
        .AsyncVal(AsyncVal),
        .Q(Q)
    );

    // 生成时钟：20ns 一个周期
    initial begin
        clk = 0;
        forever #10 clk = ~clk;
    end

    initial begin
        $display("Time | rst | AsyncVal |    D    |    Q    | Expectation");
        $monitor("%4dns |  %b  | %08b | %08b | %08b |", 
                 $time, rst, AsyncVal, D, Q);

        // 初始：复位低，D=0，AsyncVal=0
        rst = 0; D = 8'h00; AsyncVal = 8'hAA; #5;

        // 1) 异步加载测试：rst=1，Q 应立即＝AsyncVal
        rst = 1; #1;   // 在时钟边沿前就应看到 Q = 0xAA
        #9;            // 一整个时钟半周期，Q 保持

        // 2) 修改 AsyncVal，rst=1，Q 立刻跟随
        AsyncVal = 8'h55; #1;  // Q = 0x55
        #9;

        // 3) 释放异步复位 rst=0，Q 保持最后 AsyncVal
        rst = 0; #1;           // 在时钟沿前，Q = 0x55
        #9;                    // 等待时钟跳变，未改 D，所以仍 = 0x55

        // 4) 同步加载测试：D = 0x0F，在下一个 clk 上升沿 Q = D
        D = 8'h0F; #1;         // 刚释放 rst，下一个时钟应采样 D
        #9;                    // 等待时钟上升沿
        #1;                    // 刚上升沿后，Q = 0x0F

        // 5) 再次异步复位测试
        AsyncVal = 8'hFF; rst = 1; #1;  // Q = 0xFF
        #9;

        // 6) 复位释放后同步加载
        rst = 0; D = 8'hF0; #1;
        #9;                    // 下一个时钟上升沿后，Q = 0xF0

        $display("Test complete.");
        $finish;
    end

endmodule
